import type { Ref } from 'vue';
import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
import { nextTick } from 'vue';

export interface AttachmentInfo {
  name: string;
  url?: string;
  size?: number;
  type?: string; // mime type
}

export type MessageItem = BubbleProps & {
  key: number;
  role: 'ai' | 'user' | 'system';
  avatar: string;
  thinkingStatus?: ThinkingStatus;
  thinlCollapse?: boolean;
  reasoning_content?: string;
  thinkingStartTime?: number;
  thinkingTime?: number;
  attachments?: AttachmentInfo[];
  agent?: string;
};

interface BuildDeps {
  chatService: any;
  filesStore: any;
  userStore: any;
  appStore: any;
  chatStore: any;
  getWorkflowMessages?: (params: any) => Promise<any>;
  agentAvatar: string;
  getUserAvatar: () => string;
  bubbleItems: Ref<MessageItem[]>;
  bubbleListRef: Ref<BubbleListInstance | null>;
  inputValue: Ref<string>;
  isLoading: Ref<boolean>;
  resultWidth: Ref<number>;
  currentAgent?: Ref<string>;
}

export function buildChatHandlers(deps: BuildDeps) {
  const {
    chatService,
    filesStore,
    userStore,
    appStore,
    chatStore,
    getWorkflowMessages,
    agentAvatar,
    getUserAvatar,
    bubbleItems,
    bubbleListRef,
    inputValue,
    isLoading,
    resultWidth,
    currentAgent,
  } = deps;

  let abortController: AbortController | null = null;
  let currentTaskId: string | null = null;

  // 滚动到底部 - 仅用于新增会话场景
  function scrollToBottom() {
    bubbleListRef.value?.scrollToBottom();
  }

  function initResultWidth() {
    const savedWidth = localStorage.getItem('resultWidth');
    if (savedWidth) {
      const width = Number.parseInt(savedWidth);
      if (width >= 60 && width <= 100)
        resultWidth.value = width;
    }
  }

  function splitThink(answer: string | undefined): { reasoning: string; result: string } {
    const text = answer || '';
    const start = text.indexOf('<think>');
    const end = text.indexOf('</think>');
    if (start !== -1 && end !== -1 && end > start)
      return { reasoning: text.slice(start + 7, end).trim(), result: text.slice(end + 8).trim() };
    if (start !== -1 && (end === -1 || end < start))
      return { reasoning: text.slice(start + 7).trim(), result: '' };
    return { reasoning: '', result: text };
  }

  async function loadConversationById(conversationId: string) {
    // 优先使用本地缓存
    const existingChats = chatStore?.chatMap?.[`${conversationId}`];
    if (existingChats && Array.isArray(existingChats) && existingChats.length > 0) {
      bubbleItems.value = existingChats as any;
      // 加载历史消息时滚动到底部
      nextTick(scrollToBottom);
      return;
    }

    // 工作流 v1 历史消息
    if (typeof getWorkflowMessages === 'function') {
      try {
        const user = userStore.userInfo?.username || 'guest';
        const resp = await getWorkflowMessages({ user, conversation_id: String(conversationId), limit: 50 });
        const items = Array.isArray(resp) ? resp : [];
        items.sort((a: any, b: any) => (a.created_at || 0) - (b.created_at || 0));

        const mapped: MessageItem[] = [];
        let keyIndex = 0;
        for (const msg of items) {
          if (msg.query) {
            const attachments: AttachmentInfo[] = Array.isArray(msg.message_files)
              ? msg.message_files.map((f: any) => ({
                  name: f.file_name || f.filename,
                  url: f.url,
                  size: f.file_size,
                  type: f.mime_type || f.mimeType || f.type,
                }))
              : [];
            mapped.push({
              key: keyIndex++,
              role: 'user',
              avatar: getUserAvatar(),
              avatarSize: '32px',
              placement: 'end',
              isMarkdown: false,
              loading: false,
              content: msg.query,
              reasoning_content: '',
              thinkingStatus: 'end',
              thinlCollapse: true,
              noStyle: false,
              attachments,
            } as MessageItem);
          }
          if (msg.answer) {
            const { reasoning, result } = splitThink(msg.answer);
            // 从消息的inputs中提取agent信息
            const agentFromInputs = msg.inputs?.agent || msg.agent;
            mapped.push({
              key: keyIndex++,
              role: 'system',
              avatar: agentAvatar,
              avatarSize: '32px',
              placement: 'start',
              isMarkdown: true,
              loading: false,
              content: result,
              reasoning_content: reasoning,
              thinkingStatus: 'end',
              thinlCollapse: true,
              noStyle: true,
              agent: agentFromInputs || currentAgent?.value,
            } as MessageItem);
          }
        }

        if (mapped.length) {
          bubbleItems.value = mapped;
          chatService.setConversationId(String(conversationId));
        }
        else {
          // 回退到系统会话接口
          await chatStore.requestChatList(`${conversationId}`);
          const newChats = chatStore.chatMap[`${conversationId}`];
          if (newChats && Array.isArray(newChats)) {
            bubbleItems.value = newChats as any;
            chatService.setConversationId(String(conversationId));
          }
        }
      }
      catch {
        await chatStore.requestChatList(`${conversationId}`);
        const newChats = chatStore.chatMap[`${conversationId}`];
        if (newChats && Array.isArray(newChats)) {
          bubbleItems.value = newChats as any;
          chatService.setConversationId(String(conversationId));
        }
      }
      nextTick(scrollToBottom);
    }
  }

  function handleWorkflowChunk(chunk: any) {
    try {
      if (chunk?.task_id && !currentTaskId)
        currentTaskId = chunk.task_id;

      if (chunk.answer) {
        if (Array.isArray(bubbleItems.value) && bubbleItems.value.length > 0) {
          const lastMessage = bubbleItems.value[bubbleItems.value.length - 1];
          if (lastMessage) {
            const reasoning: string = chunk.reasoning ?? '';
            const result: string = chunk.result ?? '';
            if (reasoning && !result) {
              lastMessage.thinkingStatus = 'thinking';
              lastMessage.loading = true;
              lastMessage.thinlCollapse = true;
              lastMessage.reasoning_content = reasoning;
            }
            else {
              lastMessage.content = result || chunk.answer;
              lastMessage.thinkingStatus = 'end';
              lastMessage.loading = false;
              if (lastMessage.thinkingStartTime && lastMessage.thinkingTime == null && (chunk.reasoningEnded || result)) {
                const thinkingDuration = Math.round((Date.now() - lastMessage.thinkingStartTime) / 1000);
                lastMessage.thinkingTime = thinkingDuration;
              }
            }

            // 流式输出拼接时不需要手动滚动，BubbleList组件会自动处理
            // 移除: debouncedScrollToBottom();

            if (chunk.metadata?.conversation_id)
              chatService.setConversationId(chunk.metadata.conversation_id);
          }
        }
      }
    }
    catch (err) {
      console.error('处理工作流响应数据时出错:', err);
    }
  }

  function handleError(err: any) {
    console.error('Fetch error:', err);
  }

  function addMessage(message: string, isUser: boolean, attachments: AttachmentInfo[] = []) {
    if (!Array.isArray(bubbleItems.value))
      bubbleItems.value = [] as any;
    const i = bubbleItems.value.length;
    const obj: MessageItem = {
      key: i,
      avatar: isUser ? getUserAvatar() : agentAvatar,
      avatarSize: '32px',
      role: isUser ? 'user' : 'system',
      placement: isUser ? 'end' : 'start',
      isMarkdown: !isUser,
      loading: !isUser,
      content: message || '',
      reasoning_content: '',
      thinkingStatus: 'start',
      thinlCollapse: true,
      noStyle: !isUser,
      thinkingStartTime: !isUser ? Date.now() : undefined,
      thinkingTime: undefined,
      attachments: isUser ? attachments : undefined,
      agent: !isUser ? currentAgent?.value : undefined,
    };
    bubbleItems.value.push(obj);
    // 新增消息后滚动到底部
    nextTick(scrollToBottom);
  }

  async function startSSE(chatContent: string) {
    try {
      inputValue.value = '';
      const currentAttachments: AttachmentInfo[] = (filesStore.filesList || []).map((f: any) => ({
        name: f.name || f.file?.name,
        url: f.url,
        size: f.size || f.file?.size,
        type: f.type || f.file?.type,
      }));
      // 立即清空选择区，避免发送后仍显示
      try {
        filesStore.setFilesList?.([]);
      }
      catch { }
      addMessage(chatContent, true, currentAttachments);
      addMessage('', false);
      // addMessage内部已经处理滚动，这里不需要重复调用
      isLoading.value = true;

      const files = await chatService.uploadFilesIfNeeded(filesStore.filesList || [], userStore.userInfo?.username || 'guest');
      await chatService.sendMessageStream(
        chatContent,
        {},
        files,
        (chunk: any) => {
          handleWorkflowChunk(chunk);
        },
        (error: any) => {
          console.error('流式消息错误:', error);
          handleError(error);
        },
        currentAgent?.value,
        // { pre_prompt: appStore.isDeepThinking ? '/think' : '/no_think' },
      );
    }
    catch (err) {
      handleError(err);
    }
    finally {
      isLoading.value = false;
      currentTaskId = null;
      // 发送完成后，清空已选择的附件
      try {
        filesStore.setFilesList?.([]);
      }
      catch { }
      if (Array.isArray(bubbleItems.value) && bubbleItems.value.length > 0) {
        const lastMessage = bubbleItems.value[bubbleItems.value.length - 1];
        if (lastMessage) {
          lastMessage.typing = false;
          lastMessage.loading = false;
          lastMessage.thinkingStatus = 'end';
          lastMessage.thinlCollapse = true;
        }
      }
    }
  }

  async function cancelSSE() {
    if (currentTaskId) {
      try {
        await chatService.stopMessage(currentTaskId);
      }
      finally {
        currentTaskId = null;
      }
    }
    // 取消发送时也清空附件
    try {
      filesStore.setFilesList?.([]);
    }
    catch { }
    isLoading.value = false;
    if (abortController) {
      abortController.abort();
      abortController = null;
    }

    if (Array.isArray(bubbleItems.value) && bubbleItems.value.length > 0) {
      const lastMessage = bubbleItems.value[bubbleItems.value.length - 1];
      if (lastMessage) {
        lastMessage.typing = false;
        lastMessage.loading = false;
        lastMessage.thinkingStatus = 'end';
        lastMessage.thinlCollapse = true;
        if (lastMessage.thinkingStartTime && lastMessage.thinkingTime == null) {
          const thinkingDuration = Math.round((Date.now() - lastMessage.thinkingStartTime) / 1000);
          lastMessage.thinkingTime = thinkingDuration;
        }
        if (!lastMessage.reasoning_content || lastMessage.reasoning_content.trim() === '')
          lastMessage.reasoning_content = '思考过程已被用户中断';
        if (!lastMessage.content || lastMessage.content.trim() === '')
          lastMessage.content = '回答已被用户中断';
      }
    }
    isLoading.value = false;
  }

  function handleDeleteCard(_item: any, index: number) {
    filesStore.deleteFileByIndex(index);
  }

  return {
    initResultWidth,
    splitThink,
    handleWorkflowChunk,
    loadConversationById,
    startSSE,
    cancelSSE,
    addMessage,
    handleDeleteCard,
    scrollToBottom,
  };
}
